using System;
using System.Xml;
using Microsoft.SharePoint;
using VariationSettings.Enums;

namespace VariationSettings
{
    /// <summary>
    /// This class contains all logic for importing and exporting
    /// </summary>
    internal static class WorkerBee
    {
        /// <summary>
        /// Exports the variationlabels and settings to a xmldocument
        /// </summary>
        /// <param name="inputs">The parsed commandline arguments</param>
        /// <param name="rootweb">The SPWeb from where the variations should be exported</param>
        internal static void ExportSettings(ProgramInputs inputs, SPWeb rootweb)
        {
            XmlDocument exportSettings = new XmlDocument();
            exportSettings.AppendChild(exportSettings.CreateXmlDeclaration("1.0", "utf-8", null));
            XmlNode nodeSettings = exportSettings.CreateNode(XmlNodeType.Element, "VariationSettings", "");
            exportSettings.AppendChild(nodeSettings);

            // export the variationsettings from the list
            SPList varRelationshipsList = GetVariationsList(rootweb, ListType.VariationSettings);
            SPFolder fldr = varRelationshipsList.RootFolder;
            foreach (string key in fldr.Properties.Keys)
            {
                if (!key.StartsWith("vti_", StringComparison.InvariantCultureIgnoreCase))
                {
                    XmlAttribute attrib = exportSettings.CreateAttribute(key);
                    attrib.Value = fldr.Properties[key].ToString();
                    nodeSettings.Attributes.Append(attrib);
                }
            }

            // exporting the root url
            if (varRelationshipsList.Items.Count == 1)
            {
                SPListItem variationroot = varRelationshipsList.Items[0];
                string serverRelativeUrl  = variationroot["ObjectID"].ToString();

                XmlNode nodeVariationRoot = exportSettings.CreateNode(XmlNodeType.Element, "VariationRoot", "");
                nodeVariationRoot.InnerText = serverRelativeUrl;
                nodeSettings.AppendChild(nodeVariationRoot);
            }

            //export the variationlabels from the list
            SPList varLabelsList = GetVariationsList(rootweb, ListType.VariationLabels);
            foreach (SPListItem varlabel in varLabelsList.Items)
            {
                XmlNode nodeLabel = exportSettings.CreateNode(XmlNodeType.Element, "VariationLabel", "");
                nodeSettings.AppendChild(nodeLabel);

                nodeLabel.AppendChild(GetItemProperty(exportSettings, varlabel, "Title"));
                nodeLabel.AppendChild(GetItemProperty(exportSettings, varlabel, "Description"));
                nodeLabel.AppendChild(GetItemProperty(exportSettings, varlabel, "Language"));
                nodeLabel.AppendChild(GetItemProperty(exportSettings, varlabel, "Locale"));
                nodeLabel.AppendChild(GetItemProperty(exportSettings, varlabel, "Flag Control Display Name"));
                nodeLabel.AppendChild(GetItemProperty(exportSettings, varlabel, "Hierarchy Creation Mode"));
                nodeLabel.AppendChild(GetItemProperty(exportSettings, varlabel, "Is Source"));
                nodeLabel.AppendChild(GetItemProperty(exportSettings, varlabel, "Hierarchy Is Created", Boolean.FalseString));
            }

            exportSettings.Save(inputs.FileName);
        }

        /// <summary>
        /// Inports the variationlabels and settings from the xmldocument
        /// </summary>
        /// <param name="inputs"></param>
        /// <param name="rootweb"></param>
        internal static void ImportSettings(ProgramInputs inputs, SPWeb rootweb)
        {
            XmlDocument importSettings = new XmlDocument();
            importSettings.Load(inputs.FileName);
            XmlNode nodeSettings = importSettings.DocumentElement;

            // import the variationsettings to the list
            SPList varRelationshipsList = GetVariationsList(rootweb, ListType.VariationSettings);
            SPFolder fldr = varRelationshipsList.RootFolder;
            foreach (XmlAttribute attrib in nodeSettings.Attributes)
            {
                fldr.Properties[attrib.Name] = attrib.Value;
            }
            fldr.Update();

            //importing the root url
            XmlNode nodeVariationRoot = importSettings.SelectSingleNode("VariationSettings/VariationRoot");
            if (nodeVariationRoot != null)
            {
                SPListItem variationroot;
                if (varRelationshipsList.Items.Count == 1)
                {
                    variationroot = varRelationshipsList.Items[0];
                }
                else
                {
                    variationroot = varRelationshipsList.Items.Add();
                    variationroot["GroupID"] = "F68A02C8-2DCC-4894-B67D-BBAED5A066F9";
                    variationroot["Deleted"] = false;
                    variationroot.SystemUpdate(false);

                }
                variationroot["ObjectID"] = nodeVariationRoot.InnerText;
                variationroot.SystemUpdate(false);
            }

            // import the variationlabels to the list
            SPList varLabelsList = GetVariationsList(rootweb, ListType.VariationLabels);
            XmlNodeList labels = nodeSettings.SelectNodes("VariationLabel");
            foreach (XmlNode varnode in labels)
            {
                if (!VariationLabelExists(varLabelsList, varnode.SelectSingleNode("Title").InnerText))
                {
                    SPListItem variationitem = varLabelsList.Items.Add();
                    foreach (XmlNode fieldnode in varnode.ChildNodes)
                    {
                        string fieldname = fieldnode.Name.Replace("_", " ");
                        variationitem[fieldname] = fieldnode.InnerText;
                    }
                    variationitem.SystemUpdate(false);
                }
            }
        }

        #region listItem functions

        /// <summary>
        /// Creates a xmlnode from a field in a listitem
        /// </summary>
        /// <param name="doc">the xmldocument</param>
        /// <param name="item">the listitem</param>
        /// <param name="fieldname">the field to export</param>
        /// <returns>xmlnode</returns>
        private static XmlNode GetItemProperty(XmlDocument doc, SPListItem item, string fieldname)
        {
            return GetItemProperty(doc, item, fieldname, string.Empty);
        }

        /// <summary>
        /// Creates a xmlnode from a field in a listitem
        /// </summary>
        /// <param name="doc">the xmldocument</param>
        /// <param name="item">the listitem</param>
        /// <param name="fieldname">the field to export</param>
        /// <param name="overridevalue">don't use the actual fieldvalue, but use this one</param>
        /// <returns>xmlnode</returns>
        private static XmlNode GetItemProperty(XmlDocument doc, SPListItem item, string fieldname, string overridevalue)
        {
            string nodename = fieldname.Replace(" ", "_");
            XmlNode node = doc.CreateNode(XmlNodeType.Element, nodename, "");
            if (string.IsNullOrEmpty(overridevalue))
            {
                node.InnerText = item[fieldname].ToString();
            }
            else
            {
                node.InnerText = overridevalue;
            }
            return node;
        }

        /// <summary>
        /// Checks is a variationlabel allready exists in de variationlabels list
        /// </summary>
        /// <param name="list">The variationlabels list</param>
        /// <param name="title">The title of the listitem</param>
        /// <returns>true if label exists</returns>
        private static bool VariationLabelExists(SPList list, string title)
        {
            bool exists = false;

            foreach(SPListItem item in list.Items)
            {
                if (string.Equals(item["Title"].ToString(), title, StringComparison.InvariantCultureIgnoreCase))
                    return true;
            }

            return exists;
        }

        #endregion

        #region list functions

        /// <summary>
        /// 
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listtype"></param>
        /// <returns></returns>
        private static SPList GetVariationsList(SPWeb web, ListType listtype)
        {
            string propid = string.Empty;

            switch (listtype)
            {
                case ListType.VariationSettings:
                    propid = web.AllProperties["_VarRelationshipsListId"].ToString();
                    break;
                case ListType.VariationLabels:
                    propid = web.AllProperties["_VarLabelsListId"].ToString();
                    break;
                default:
                    break;
            }

            if (!string.IsNullOrEmpty(propid))
            {
                Guid listid = new Guid(propid);
                return web.Lists[listid];
            }
            return null;
        }

        #endregion
    }
}